from django.shortcuts import render, redirect
# 导包
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
# 导入类视图
from django.views import View
import json
from django.core.serializers import serialize
from rest_framework.response import Response
from rest_framework.views import APIView
# 导入加密库
import hashlib
# 导入图片库
# 绘画库
from PIL import ImageDraw
# 字体库
from PIL import ImageFont
# 图片库
from PIL import Image
# 随机库
import random
# 文件流
import io

import requests

# 导入上传文件夹配置
from mydjango.settings import UPLOAD_ROOT
import os

# 导入原生sql模块
from django.db import connection

import jwt

# 导入redis数据库
import redis

# 导入时间模块
import time

# 导入公共目录变量
from mydjango.settings import BASE_DIR

# 导包
from django.db.models import Q, F

# 导入dwebsocket的库
from dwebsocket.decorators import accept_websocket
import uuid
# 导入序列化对象
# from myapp.myser import UserSer
from myapp.models import User
# 导包
import redis
# 导入中间件
from django.utils.deprecation import MiddlewareMixin

from myapp.myser import CarouserlSer
from myapp.myser import *
# 定义ip端口
host = "localhost"
port = 6379
# 建立连接
r = redis.Redis(host=host, port=port)


class GetUsers(APIView):
    def get(self,request):
        user = User.objects.filter().values('id','username')
        users=list(user)

        return JsonResponse(users,safe=False,json_dumps_params={'ensure_ascii':False})


class GetCarousel(APIView):
    def get(self,request):
        #读库
        carousels = Carousel.objects.all()
        #序列号操作
        carousels_ser = CarouserlSer(carousels,many=True)
        return Response({'data':carousels_ser.data})
# 自定义中间件
# class MyMiddleware(MiddlewareMixin):
#     def process_request(self, request):
#         # 获取路由
#         if request.path_info.startswith('/userinfo/'):
#             return JsonResponse({"message": '页面失踪'}, safe=False,
#                                 json_dumps_params={'ensuer_ascii': False})
#
#             # return HttpResponse(json.dumps({' message': '您篡改了uid'},ensure_ascii=False,indent=4),
#             #                     content_type= ' application/json')
#         pass
#     def process_view(self, request, view_func, view_args, view_kwargs):
#         pass
#
#     def process_exception(self, request, exception):
#         pass
#
#     def process_response(self, request, response):
#         pass


# 获取用户信息
class UserInfo(APIView):
    def get(self, request):
        # 接受参数
        uid = request.GET.get('uid')
        myjwt = request.GET.get('jwt')
        # 验证用户合法性
        decode_jwt = jwt.decode(myjwt, 'qwe123', algorithms=['HS256'])
        # 进行对比
        if int(uid) != int(decode_jwt['uid']):
            return Response({'code': 401, 'message': '页面神秘失踪'})

        # 查询数据库
        user = User.objects.get(id=int(uid))
        # 返回
        return Response({'img': user.img})


# 七牛云token
from qiniu import Auth


class QiNiu(APIView):
    def get(self, request):
        # 声明认证对象
        q = Auth('pzWBKLXJDK9sFbg-dbSdUj7p2XAHmsvOf6Sp6o6N',
                 '16tcgCc3hLurHa_J2ef1vFxo9Z3OKNLOXun-DHBC')
        # 获取token
        token = q.upload_token('whcupload')

        return Response({'token': token})


import uuid


# 文件上传通用类
class UploadFile(APIView):

    def post(self, request):
        # 接受参数
        myfile = request.FILES.get('file')
        print(myfile)
        uid = request.POST.get('uid')
        print('www', myfile)
        myfile.name = str(uuid.uuid4()) + '.jpg'
        # 上传的文件是一个对象
        # myfilename=myfile.name.replace('"','')
        # 建立文件流对象
        # f = open(os.path.join(UPLOAD_ROOT,'',myfilename),'wb')
        f = open(os.path.join(UPLOAD_ROOT, '', myfile.name), 'wb')
        # 写入
        for chunk in myfile.chunks():
            f.write(chunk)
        f.close()

        # 修改头像地址
        user = User.objects.get(id=int(uid))
        user.img = myfile.name.replace('"', '')
        user.save()

        return Response({'filename': myfile.name})


# 又拍云存储
# 又拍云存储
import upyun


class UpYunn(APIView):
    def post(self, request):
        # 获取文件
        file = request.FILES.get('file')
        print(11111111111111111)
        print(file)
        # 新建又拍云实例
        up = upyun.UpYun('flies123adc', username='qwe123', password='101tbBRjSUFAqwjXOcB3Uc0QpSkiN9ig')
        # 声明头部信息
        print('up', up)
        headers = {'x-gmkerl-rotate': 'auto'}
        # 上传图片
        for chunk in file.chunks():
            print('chunk', chunk)
            res = up.put('/%s' % file, chunk, checksum=True, headers=headers)
            print('res', res)
        return Response({'filename': file.name})


# 新浪微博回调
def wb_back(request):
    # 接受参数
    code = request.GET.get('code', None)
    # 定义token接口地址
    url = "https://api.weibo.com/oauth2/access_token"
    # 定义参数
    re = requests.post(url, data={
        'client_id': '1721358960',
        'client_secret': '6c3aae7af5600f10b9a0b40b6a952d01',
        "grant_type": "authorization_code",
        'code': code,
        "redirect_uri": "http://127.0.0.1:8000/md_admin/weibo"
    })
    print(re.json())

    # 换取新浪用户昵称
    res = requests.get('https://api.weibo.com/2/users/show.json',
                       params={'access_token': re.json()['access_token'], 'uid': re.json()['uid']})
    sina_id = ''
    user_id = ''
    # 判断是否登陆过
    user = User.objects.filter(username=str(res.json()['name'])).first()
    if user:
        # 代码曾经用该账号登陆过
        sina_id = user.username
        user_id = user.id
    else:
        user = User(username=str(res.json()['name']), password='')
        user.save()
        user = User.objects.filter(username=str(res.json()['name'])).first()
        sina_id = user.username
        user_id = user.id
    print(sina_id, user_id)

    return redirect('http://127.0.0.1:8080?sina_id=' + str(sina_id) + "&uid=" + str(user_id))


class MyCode(View):
    # 定义rgb随机颜色
    def get_randow_color(self):
        R = random.randrange(255)
        G = random.randrange(255)
        B = random.randrange(255)
        return (R, G, B)

    # 定义图片视频
    def get(self, request):
        # 画布
        img_size = (120, 50)
        # 定义图片对象
        image = Image.new('RGB', img_size, 'white')
        # 定义画笔
        draw = ImageDraw.Draw(image, 'RGB')
        source = '213456789qwertyuiokmnbvcx'
        # 接受容器
        code_str = ''
        # 进入循环回值
        for i in range(4):
            # 获取字母颜色
            text_color = self.get_randow_color()
            # 获取随机下标
            tmp_num = random.randrange(len(source))
            # 随机子符串
            random_str = source[tmp_num]
            # 装入容器中
            code_str += random_str
            # 绘制字符串 横坐标 ，纵坐标
            draw.text((10 + 30 * i, 20), random_str, text_color)
        # 获取缓存区
        buf = io.BytesIO()
        # 临时图片保存到缓冲
        image.save(buf, 'png')
        # 保存随机码
        r.set('code', code_str)
        # print(r.get('code'))
        # 保存session
        request.session['code'] = code_str

        return HttpResponse(buf.getvalue(), 'image/png')


# md5加密方法 django内置的password原理
def make_password(mypass):
    # 生成md5对象
    md5 = hashlib.md5()
    # 转码操作
    mypass_utf8 = str(mypass).encode(encoding='utf-8')
    # 加密操作
    md5.update(mypass_utf8)
    # 返回密文
    return md5.hexdigest()


# 注册接口
class Register(APIView):
    def get(self, request):
        # 接受参数
        username = request.GET.get('username', None)
        password = request.GET.get('password', None)
        phone = request.GET.get('phone', None)
        # 排重
        user = User.objects.filter(username=username).first()
        if user:
            return Response({'code': 403, 'message': '该用户名已存在'})
        # 入库
        user = User(username=username, password=make_password(password), phone=phone)
        # 保存结果
        user.save()
        return Response({'code': 200, 'message': '注册成功'})
    # def post(self, request):
    #     # 接受参数
    #     username = request.POST.get('username', None)
    #     password = request.POST.get('password', None)
    #     #排重
    #     user=User.objects.filter(username=username).first()
    #     if user:
    #         return Response({'code':403,'message':'该用户名已存在'})
    #     #入库
    #     user = User(username=username,password=make_password(password))
    #     #保存结果
    #     user.save()
    #     return Response({'code':200,'message':'注册成功'})


# 登录接口
class Login(APIView):
    def get(self, request):
        # 接受参数
        username = request.GET.get('username', None)
        password = request.GET.get('password', None)
        code = request.GET.get('code')
        # 比对验证码
        redis_code = r.get('code')
        # 转码
        redis_code = redis_code.decode('utf-8')

        # 从session取值
        # session_code = request.session.get('code',None)
        # print('session:',session_code)
        if code != redis_code:
            return Response({'code': 403, 'message': '验证码输入错误'})

        # 查询数据
        user = User.objects.filter(Q(username=username) | Q(phone=username), password=make_password(password)).first()
        # 如果密码正确，而且输入错误的次数小于5，就判断登录成功
        if user and r.llen(username) < 5:
            # 生成用户token
            encode_jwt = jwt.encode({'uid': user.id}, 'qwe123', algorithm='HS256')
            encode_str = str(encode_jwt, 'utf-8')

            return Response({'code': 200, 'message': '登陆成功', 'uid': user.id,
                             'username': user.username, 'jwt': encode_str})
        else:
            # 设置账号锁定，如果user查询不到，就往列表里面添加一条数据
            r.lpush(username, 1)
            # 如果长度等于5，就将账号锁定
            if r.llen(username) == 5:
                r.expire(username, 60)
            # 如果继续输入错误，就返回提示信息
            if r.llen(username) > 5:
                return Response({'code': 403, 'message': '您的账号已被锁定，%s秒以后再次输入' % r.ttl(username)})
            # 给予5次尝试机会
            return Response({'code': 403, 'message': '您的账号或者密码错误'})
